#pragma once
#include "rocksdb/slice.h"
#include "util/coding.h"
#include "db/dbformat.h"
#include "rocksdb/env.h"

namespace rocksdb {

    class MvccKey {
    public:
        Slice userKey_;
        Slice timestamp_;
        Slice userKeyWithTime_;
        uint64_t seqNumAndType_;
        Logger* logger_;

    public:
        MvccKey(Logger* log = nullptr) : logger_(log){}
        inline bool parseKey(Slice buf) {
          assert(!buf.empty());

          seqNumAndType_ = DecodeFixed64(buf.data() + buf.size() - 8);
          if (buf.size() == 8) {
              userKey_ = Slice(buf.data(), 0);
              timestamp_ = Slice(buf.data(), 0);
              userKeyWithTime_ = Slice(buf.data(), 0);
              return true;
          }
          Slice mvccKey = Slice(buf.data(), buf.size() - 8);
          const char ts_size = mvccKey[mvccKey.size() - 1];
          if ((size_t) ts_size >= mvccKey.size()) {
            ROCKS_LOG_WARN(logger_, "cannot parse key:%s, ts_size:%lu  larger than length: %lu ",
                buf.ToString(true).c_str(), (size_t) ts_size, mvccKey.size());
            userKey_ = mvccKey;
            timestamp_ = Slice(buf.data(), 0);
            userKeyWithTime_ = mvccKey;
            return true;
          }
          userKey_ = Slice(mvccKey.data(), mvccKey.size() - ts_size - 1);
          timestamp_ = Slice(userKey_.data() + userKey_.size(), ts_size);
          userKeyWithTime_ = mvccKey;

          return true;
        }

        void dump(Logger *logger = nullptr) const {
          ROCKS_LOG_DEBUG(logger,"userkey:%s, timestamp:%s, seqAndType: %lu", 
            userKey_.ToString(true).c_str(),timestamp_.ToString(true).c_str(), seqNumAndType_);
        }
    };
}